package fcy.ui;

import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.util.Log;
import android.view.*;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;

import com.github.mikephil.charting.animation.Easing;
import com.github.mikephil.charting.charts.BarLineChartBase;
import com.github.mikephil.charting.charts.Chart;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.Legend.LegendForm;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.LimitLine.LimitLabelPosition;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.data.filter.Approximator;
import com.github.mikephil.charting.data.filter.Approximator.ApproximatorType;
import com.github.mikephil.charting.formatter.FillFormatter;
import com.github.mikephil.charting.formatter.ValueFormatter;
import com.github.mikephil.charting.formatter.XAxisValueFormatter;
import com.github.mikephil.charting.formatter.YAxisValueFormatter;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.interfaces.dataprovider.LineDataProvider;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.github.mikephil.charting.listener.ChartTouchListener;
import com.github.mikephil.charting.listener.OnChartGestureListener;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
import com.github.mikephil.charting.renderer.XAxisRenderer;
import com.github.mikephil.charting.utils.ViewPortHandler;
import com.xxmassdeveloper.mpchartexample.R;
import com.xxmassdeveloper.mpchartexample.custom.MyMarkerView;
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;

import java.util.ArrayList;
import java.util.List;

public class SimpleLineChartActivity extends DemoBase implements OnSeekBarChangeListener,
	OnChartGestureListener, OnChartValueSelectedListener {

	private LineChart mChart;
	private SeekBar mSeekBarX, mSeekBarY;
	private TextView tvX, tvY;

	private void initDescription() {
		// no description text
		mChart.setDescription("Description");
		mChart.setDescriptionColor(Color.BLUE);
		mChart.setDescriptionTextSize(30);
//        mChart.setDescriptionPosition(520,400);
		// 默认位置
		// (mDescription, getWidth() - mViewPortHandler.offsetRight() - 10,
		// getHeight() - mViewPortHandler.offsetBottom()- 10)
		mChart.setContentDescription("我去");
		mChart.setNoDataText("NoDataText");
		mChart.setNoDataTextDescription("NoDataTextDescription");
	}

	private void initAxis() {
		// --------------- X轴 ------------------
		// x轴只有一个坐标轴，默认在top TODO查看每个方法的含义
		XAxis xAxis = mChart.getXAxis();
		xAxis.setYOffset(20);
		// 把X坐标轴放置到底部。默认的是在顶部。
		xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
		// 使用虚线
		xAxis.enableGridDashedLine(10f, 10f, 0f);
//		xAxis.disableGridDashedLine();
		// X轴坐标线的颜色（是底部标度线颜色，不是网格）
		xAxis.setAxisLineColor(Color.RED);
		// X轴网格线颜色
		xAxis.setGridColor(Color.BLUE);

		// 禁用所有（下面3个都不绘制了）
		//xAxis.setEnabled(false);
//		// 不显示X标度值
//		xAxis.setDrawLabels(false);
//		// 不显示X轴
		xAxis.setDrawAxisLine(true);
//		// 不绘制竖直网格线
		xAxis.setDrawGridLines(false);

		// 每隔几个label绘制一个，通过修改mAxisLabelModulus,绘制的时候是只绘制xIndex%mAxisLabelModulus==0
		xAxis.setLabelsToSkip(1);
		// 设置两个label之间的最小间距，如果两个label之间的距离小于这个值，就不会绘制
//		xAxis.setSpaceBetweenLabels(20);
//		xAxis.setValueFormatter(new MyCustomXAxisValueFormatter());
		// format xValues是String
		xAxis.setValueFormatter(new XAxisValueFormatter() {
			@Override
			public String getXValue(String original, int index, ViewPortHandler viewPortHandler) {
				//return original + "明月晓溪";
				return original + "月";
			}
		});
		// --------------------------------------

		// ------ x-axis limit line 水平方向Limit Line ------
		Typeface tf = Typeface.createFromAsset(getAssets(), "OpenSans-Regular.ttf");
		LimitLine ll1 = new LimitLine(50f, "Upper Limit");
		ll1.setLineWidth(4f);
		ll1.enableDashedLine(10f, 10f, 0f);
		ll1.setLabelPosition(LimitLabelPosition.RIGHT_TOP);
		ll1.setTextSize(10f);
		ll1.setTypeface(tf);

		LimitLine ll2 = new LimitLine(-30f, "Lower Limit");
		ll2.setLineWidth(4f);
		ll2.enableDashedLine(10f, 10f, 0f);
		ll2.setLabelPosition(LimitLabelPosition.RIGHT_BOTTOM);
		ll2.setTextSize(10f);
		ll2.setTypeface(tf);

		// --------------- leftY轴 ------------------
		YAxis axisLeft = mChart.getAxisLeft();
		// zeroline 设置后zeroline将不使用网格线
//		axisLeft.setDrawZeroLine(true);
//		axisLeft.setZeroLineColor(Color.BLUE);
		axisLeft.setDrawGridLines(false);
		axisLeft.setXOffset(20);
		// 设置yVals的基数和单位，只是y轴显示的刻度改变（yVals/unit + 单位），真实的yVals并不会改变
		// fixme 去除这个添加的api，使用setValueFormatter
//		axisLeft.setUnit(10f,"万元");
		// 设置y轴顶部的标度距离表格的space Sets the top axis space in percent of the full range. Default 10f
		axisLeft.setSpaceTop(50); // 默认10源码如下
		/*if (!mCustomAxisMin) {

			float bottomSpace = range / 100f * getSpaceBottom();
			this.mAxisMinimum = (min - bottomSpace);
		}

		// top-space only effects non-custom max
		if (!mCustomAxisMax) {

			float topSpace = range / 100f * getSpaceTop();
			this.mAxisMaximum = (max + topSpace);
		}*/

		// 如果需要显示单位等，
		axisLeft.setValueFormatter(new YAxisValueFormatter() {
			@Override
			public String getFormattedValue(float value, YAxis yAxis) {
				return (int) value / 10 + "万";
				//return (int) value / 10 + "你微笑时很美";
			}
		});
		YAxis leftAxis = mChart.getAxisLeft();
		leftAxis.removeAllLimitLines(); // reset all limit lines to avoid overlapping lines
		leftAxis.addLimitLine(ll1);
		leftAxis.addLimitLine(ll2);
//		leftAxis.setLabelCount(3,true);
//		leftAxis.setShowOnlyMinMax(true);
		// 设置最大可见value个数，如果当前可见节点个数超过该数值，将不显示value的值
//		mChart.setMaxVisibleValueCount(3);
		// 如果没有设置坐标轴最小、最大刻度值，那么会自动根据当前最小最大yValus去计算
//		leftAxis.setAxisMaxValue(50f);
//		leftAxis.setAxisMinValue(50f);
		// 是否左边y坐标系从0开始，如果false,但设置了setAxisMinValue会根据最小值得刻度开始。否则根据计算的单位yValues的最小值
		leftAxis.setStartAtZero(true);
		leftAxis.enableGridDashedLine(10f, 10f, 0f);

		// limit lines are drawn behind data (and not on top)
		leftAxis.setDrawLimitLinesBehindData(true);


		// --------------- 右边y轴 ----------------
		YAxis axisRight = mChart.getAxisRight();
		axisRight.setEnabled(false);
//		axisRight.setDrawLabels(true);



	}

	private void initScale() {
		// 禁掉所有的手势和touch
		mChart.setTouchEnabled(true);
		// 对barChart有效
//		mChart.setDoubleTapToZoomEnabled(true);
		// 如果设置false，x，y只能单方向缩放，默认false
		mChart.setPinchZoom(false);
//        mChart.setDragEnabled(false);
//        // enable scaling and dragging
//        mChart.setScaleEnabled(true);
		// mChart.setScaleXEnabled(true);
		// 禁止y方向缩放
		mChart.setScaleYEnabled(true);
//		mChart.setScaleX();
//		mChart.setScaleMinima();
//		mChart.setAutoScaleMinMaxEnabled(true);
//		mChart.move
	}

	private void initGrid() {
		// 是否绘制网格的边框，默认false
//		mChart.setDrawBorders(true);
//		mChart.setBorderColor(Color.RED);
		// 整个Chart的背景
//		mChart.setBackgroundColor(Color.GRAY);
		mChart.setDrawGridBackground(false);
		// 设置网格区域背景色
//		mChart.setGridBackgroundColor(Color.GREEN);
	}

	private void initPosition() {
		mChart.setBackgroundColor(Color.GREEN);
		mChart.setDrawGridBackground(true);
		mChart.setGridBackgroundColor(Color.BLUE);
		// 设置上下左右offset（px）,默认会根据text文案长度设置。
		// 网格区域的代码是这么设置的。
//		mContentRect.set(offsetLeft, offsetTop, mChartWidth - offsetRight, mChartHeight
//			- offsetBottom);
		// 设置网格区域内容相对父容器的偏移，默认会根据自己计算这个offset
//		mChart.setViewPortOffsets(100, 100, 100, 100);
//		mChart.setViewPortOffsets(0, 0, 0, 0);
		// 默认为15
//		mChart.setMinOffset(5);
		// 设置在ViewPort基础上额外的偏移量，chart网格区域在自动计算的基础上的额外offset
		// @see BarlineChartBase中的calculateOffsets方法 left的offset = legend.leftOffset+leftY.labelWidth+
		// fixme 如果rightAxis被禁掉了，那么needoffset=0,而默认minoffset=15,实际偏移量就是Math.max(rightExtraOffset,minOffset)
		mChart.setExtraOffsets(0,0,25,0);
		// 设置允许用户drag到终点越界偏移
		mChart.setDragOffsetX(20);
//		mChart.moveViewToX();

	}

	private void initLegend() {
		//  图例设置// get the legend (only possible after setting data)
		Legend mLegend = mChart.getLegend();
//		mLegend.setEnabled(false);
		//// 底部居中
		mLegend.setPosition(Legend.LegendPosition.BELOW_CHART_CENTER);
		//// 格式为圆点
		mLegend.setForm(LegendForm.CIRCLE);
		mLegend.setFormSize(8.0f);
		// 设置图例label颜色
		mLegend.setTextColor(Color.BLUE);
		mLegend.setCustomLabelColorEnable(true);
		ArrayList<String> label = new ArrayList<>();
		label.add("你好");
		label.add("哈哈");
		ArrayList<Integer> colors = new ArrayList<>();
		colors.add(Color.GREEN);
		colors.add(Color.RED);
		mLegend.setCustom(colors,label);

		// 图例距离chart左边20px
		mLegend.setXEntrySpace(20);
		//// 文字与图列图标的偏移量
		//mLegend.setFormToTextSpace(20);
		////mLegend.setXOffset(50);
		//// 设置图列竖直方向偏移量
		////mLegend.setYOffset(30);

		// get the legend (only possible after setting data)
		//Legend l = mChart.getLegend();

		//l.setFormSize(6f); // 字体大小
		//l.setTextColor(Color.RED);
	}

	private void initPoint() {

	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
			WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setContentView(R.layout.activity_linechart);

		tvX = (TextView) findViewById(R.id.tvXMax);
		tvY = (TextView) findViewById(R.id.tvYMax);

		mSeekBarX = (SeekBar) findViewById(R.id.seekBar1);
		mSeekBarY = (SeekBar) findViewById(R.id.seekBar2);

		mSeekBarX.setProgress(45);
		mSeekBarY.setProgress(100);

		mSeekBarY.setOnSeekBarChangeListener(this);
		mSeekBarX.setOnSeekBarChangeListener(this);

		mChart = (LineChart) findViewById(R.id.chart1);
		mChart.setHighlightPerDragEnabled(true);
		// 在父类BarLineChartBase构造方法中就已经初始化了onTouchListener,只能覆盖
		mChart.setOnMarkClickListener(new BarLineChartBase.OnMarkClickListener() {
			@Override
			public void clickMark(int position, Entry entry) {
				Toast.makeText(SimpleLineChartActivity.this,entry.toString(),Toast.LENGTH_SHORT).show();
			}
		});
		mChart.setDefaultChartTouchListener(false);
//		mChart.setDefaultChartTouchListener(false, new View.OnTouchListener() {
//			@Override
//			public boolean onTouch(View v, MotionEvent event) {
//				Toast.makeText(SimpleLineChartActivity.this, "哈哈", Toast.LENGTH_SHORT).show();
//				switch (event.getAction()) {
//					case MotionEvent.ACTION_UP:
//						Log.i("fcy",
//							"-----------------\n event.getX()=" + event.getX() + "event" +
//								".getY()=" + event.getY());
//						Entry entry = mChart.touch(event.getX(), event.getY());
//						Toast.makeText(SimpleLineChartActivity.this, entry.toString(), Toast.LENGTH_SHORT).show();
//						break;
//				}
//				return true;
//			}
//		});
		// ------------- 设置表格 --------------------
		initPosition();
		initGrid();
		initDescription();
		initScale();
		initAxis();
//		initLegend();

		mChart.setOnChartGestureListener(this);

		mChart.setOnChartValueSelectedListener(this);

//
		// set an alternative background color
		// mChart.setBackgroundColor(Color.GRAY);

		// create a custom MarkerView (extend MarkerView) and specify the layout
		// to use for it
		MyMarkerView mv = new MyMarkerView(this, R.layout.custom_marker_view);

		// set the marker to the chart
		mChart.setMarkerView(mv);
//		mChart.setVisibleXRangeMaximum();
//		mChart.setMaxVisibleValueCount();
//		mChart.setVisibleYRangeMaximum();

		//mChart.getViewPortHandler().setMaximumScaleY(2f);
		//mChart.getViewPortHandler().setMaximumScaleX(2f);

		// add data
		setData(12, 100);
		initLegend();

//        mChart.setVisibleXRange(20);
		// fixme
//        mChart.setVisibleYRange(20f, AxisDependency.LEFT);
//        mChart.centerViewTo(20, 50, AxisDependency.LEFT);

		mChart.animateX(2500, Easing.EasingOption.EaseInOutQuart);
//        mChart.invalidate();

//		// get the legend (only possible after setting data)
//		Legend l = mChart.getLegend();
//
//		// modify the legend ...
//		// l.setPosition(LegendPosition.LEFT_OF_CHART);
//		l.setForm(LegendForm.CIRCLE);
//
//		// // dont forget to refresh the drawing
//		// mChart.invalidate();
	}

	@Override
	public void onWindowFocusChanged(boolean hasFocus) {
		super.onWindowFocusChanged(hasFocus);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.line, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId()) {
			case R.id.actionToggleValues: {
				List<ILineDataSet> sets = mChart.getData()
					.getDataSets();

				for (ILineDataSet iSet : sets) {

					LineDataSet set = (LineDataSet) iSet;
					set.setDrawValues(!set.isDrawValuesEnabled());
				}

				mChart.invalidate();
				break;
			}
			case R.id.actionToggleHighlight: {
				if (mChart.getData() != null) {
					mChart.getData().setHighlightEnabled(!mChart.getData().isHighlightEnabled());
					mChart.invalidate();
				}
				break;
			}
			case R.id.actionToggleFilled: {

				List<ILineDataSet> sets = mChart.getData()
					.getDataSets();

				for (ILineDataSet iSet : sets) {

					LineDataSet set = (LineDataSet) iSet;
					if (set.isDrawFilledEnabled())
						set.setDrawFilled(false);
					else
						set.setDrawFilled(true);
				}
				mChart.invalidate();
				break;
			}
			case R.id.actionToggleCircles: {
				List<ILineDataSet> sets = mChart.getData()
					.getDataSets();

				for (ILineDataSet iSet : sets) {

					LineDataSet set = (LineDataSet) iSet;
					if (set.isDrawCirclesEnabled())
						set.setDrawCircles(false);
					else
						set.setDrawCircles(true);
				}
				mChart.invalidate();
				break;
			}
			case R.id.actionToggleCubic: {
				List<ILineDataSet> sets = mChart.getData()
					.getDataSets();

				for (ILineDataSet iSet : sets) {

					LineDataSet set = (LineDataSet) iSet;
					if (set.isDrawCubicEnabled())
						set.setDrawCubic(false);
					else
						set.setDrawCubic(true);
				}
				mChart.invalidate();
				break;
			}
			//case R.id.actionToggleStartzero: {
			//	mChart.getAxisLeft().setStartAtZero(!mChart.getAxisLeft().isStartAtZeroEnabled());
			//	mChart.getAxisRight().setStartAtZero(!mChart.getAxisRight().isStartAtZeroEnabled());
			//	mChart.invalidate();
			//	break;
			//}
			case R.id.actionTogglePinch: {
				if (mChart.isPinchZoomEnabled())
					mChart.setPinchZoom(false);
				else
					mChart.setPinchZoom(true);

				mChart.invalidate();
				break;
			}
			case R.id.actionToggleAutoScaleMinMax: {
				mChart.setAutoScaleMinMaxEnabled(!mChart.isAutoScaleMinMaxEnabled());
				mChart.notifyDataSetChanged();
				break;
			}
			case R.id.animateX: {
				mChart.animateX(3000);
				break;
			}
			case R.id.animateY: {
				mChart.animateY(3000, Easing.EasingOption.EaseInCubic);
				break;
			}
			case R.id.animateXY: {
				mChart.animateXY(3000, 3000);
				break;
			}
			//case R.id.actionToggleFilter: {
            //
			//	// the angle of filtering is 35°
			//	Approximator a = new Approximator(ApproximatorType.DOUGLAS_PEUCKER, 35);
            //
			//	if (!mChart.isFilteringEnabled()) {
			//		mChart.enableFiltering(a);
			//	} else {
			//		mChart.disableFiltering();
			//	}
			//	mChart.invalidate();
			//	break;
			//}
			case R.id.actionSave: {
				if (mChart.saveToPath("title" + System.currentTimeMillis(), "")) {
					Toast.makeText(getApplicationContext(), "Saving SUCCESSFUL!",
						Toast.LENGTH_SHORT).show();
				} else
					Toast.makeText(getApplicationContext(), "Saving FAILED!", Toast.LENGTH_SHORT)
						.show();

				// mChart.saveToGallery("title"+System.currentTimeMillis())
				break;
			}
		}
		return true;
	}

	@Override
	public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

		tvX.setText("" + (mSeekBarX.getProgress() + 1));
		tvY.setText("" + (mSeekBarY.getProgress()));

		setData(mSeekBarX.getProgress() + 1, mSeekBarY.getProgress());

		// redraw
		mChart.invalidate();
	}

	@Override
	public void onStartTrackingTouch(SeekBar seekBar) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onStopTrackingTouch(SeekBar seekBar) {
		// TODO Auto-generated method stub

	}

	private void setData(int count, float range) {

		ArrayList<String> xVals = new ArrayList<String>();
		for (int i = 0; i < count; i++) {
			xVals.add((i + 1) + "");
		}

		ArrayList<Entry> yVals = new ArrayList<Entry>();

		for (int i = 0; i < count; i++) {

			float mult = (range + 1);
			float val = (float) (Math.random() * mult) + 3;// + (float)
			// ((mult *
			// 0.1) / 10);
			yVals.add(new Entry(val, i));
		}

		// create a dataset and give it a type
		LineDataSet set1 = new LineDataSet(yVals, "DataSet 1");
		// set1.setFillAlpha(110);
		// set1.setFillColor(Color.RED);

		// 绘制虚线还是实线
//		set1.enableDashedLine(10f, 5f, 0f);
//		set1.disableDashedLine();
		// 绘制高亮
		set1.enableDashedHighlightLine(10f, 5f, 0f);
		set1.setDrawHorizontalHighlightIndicator(false);
//		set1.setHighLightColor();
		// 禁止高亮，包括markview和高亮indict
//		set1.setHighlightEnabled();
		set1.setValueFormatter(new ValueFormatter() {
			@Override
			public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
				return (int)value / 10 + "万";
			}
		});

		// TODO 设置填充fomatter see defaultFillFormatter
		set1.setFillFormatter(new FillFormatter() {
			@Override
			public float getFillLinePosition(ILineDataSet dataSet, LineDataProvider dataProvider) {
				return 10;
			}
		});

		set1.setColor(Color.BLACK);
		set1.setCircleColor(Color.BLACK);
		set1.setLineWidth(1f);
		set1.setCircleSize(3f);
		// 不绘制内层圆圈
		set1.setDrawCircleHole(false);
		set1.setValueTextSize(9f);
		set1.setFillAlpha(65);
		set1.setFillColor(Color.BLACK);
//        set1.setDrawFilled(true);
		// set1.setShader(new LinearGradient(0, 0, 0, mChart.getHeight(),
		// Color.BLACK, Color.WHITE, Shader.TileMode.MIRROR));

		ArrayList<ILineDataSet> dataSets = new ArrayList<ILineDataSet>();
		dataSets.add(set1); // add the datasets

		// create a data object with the datasets
		LineData data = new LineData(xVals, dataSets);

		// set data
		mChart.setData(data);
	}

	@Override
	public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
		Log.i("Gesture", "START");
	}

	@Override
	public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
		Log.i("Gesture", "END, lastGesture: " + lastPerformedGesture);

		// un-highlight values after the gesture is finished and no single-tap
		if (lastPerformedGesture != ChartTouchListener.ChartGesture.SINGLE_TAP)
			mChart.highlightValues(null); // or highlightTouch(null) for callback to onNothingSelected(...)
	}

	@Override
	public void onChartLongPressed(MotionEvent me) {
		Log.i("LongPress", "Chart longpressed.");
	}

	@Override
	public void onChartDoubleTapped(MotionEvent me) {
		Log.i("DoubleTap", "Chart double-tapped.");
	}

	@Override
	public void onChartSingleTapped(MotionEvent me) {
		Log.i("SingleTap", "Chart single-tapped.");
	}

	@Override
	public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {
		Log.i("Fling", "Chart flinged. VeloX: " + velocityX + ", VeloY: " + velocityY);
	}

	@Override
	public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
		Log.i("Scale / Zoom", "ScaleX: " + scaleX + ", ScaleY: " + scaleY);
	}

	@Override
	public void onChartTranslate(MotionEvent me, float dX, float dY) {
		Log.i("Translate / Move", "dX: " + dX + ", dY: " + dY);
	}

	@Override
	public void onValueSelected(Entry e, int dataSetIndex, Highlight h) {
		Log.i("Entry selected", e.toString());
		Log.i("", "low: " + mChart.getLowestVisibleXIndex() + ", high: " + mChart.getHighestVisibleXIndex());
	}

	@Override
	public void onNothingSelected() {
		Log.i("Nothing selected", "Nothing selected.");
	}
}
